<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>DevBox 命令手册</title>
    <!-- 预加载关键资源 -->
    <link rel="preload" href="commands.json" as="fetch" crossorigin>
    <!-- 优化 CDN 链接（使用官方稳定 CDN） -->
    <script src="https://cdn.tailwindcss.com"></script>
    <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">

    <!-- Tailwind 配置 -->
    <script>
        tailwind.config = {
          theme: {
            extend: {
              colors: {
                primary: '#165DFF',
                secondary: '#6B7280',
                dark: '#1F2937',
                light: '#F9FAFB'
              },
              fontFamily: {
                mono: ['Consolas', 'Monaco', 'Courier New', 'monospace']
              }
            }
          }
        }
    </script>

    <style type="text/tailwindcss">
        @layer utilities {
          .content-auto { content-visibility: auto; }
          .command-card { @apply bg-white rounded-lg shadow-md overflow-hidden transition-all duration-300 hover:shadow-lg hover:border-primary; }
          .command-header { @apply px-4 py-3 bg-gray-50 border-b border-gray-200 flex justify-between items-center cursor-pointer; }
          .command-body { @apply px-4 py-3 border-t border-gray-100; }
          .search-highlight { @apply bg-yellow-200 px-1 rounded; }
        }
    </style>
</head>
<body class="bg-gray-50 font-sans text-gray-800">
<!-- 顶部导航栏 -->
<header class="bg-white shadow-sm sticky top-0 z-50">
    <div class="container mx-auto px-4 py-4">
        <div class="flex flex-col md:flex-row justify-between items-center">
            <div class="flex items-center mb-4 md:mb-0">
                <i class="fa fa-terminal text-primary text-3xl mr-3"></i>
                <h1 class="text-2xl font-bold text-dark">DevBox 命令手册</h1>
            </div>
            <!-- 搜索框 -->
            <div class="w-full md:w-96">
                <div class="relative">
                    <input
                            type="text"
                            id="search-input"
                            placeholder="搜索命令..."
                            class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary/50 focus:border-primary transition-all"
                    >
                    <i class="fa fa-search absolute right-3 top-1/2 transform -translate-y-1/2 text-gray-400"></i>
                </div>
                <div id="search-results" class="absolute z-10 w-full md:w-96 mt-1 bg-white rounded-lg shadow-lg max-h-96 overflow-y-auto hidden"></div>
            </div>
        </div>
    </div>
</header>

<!-- 主要内容区 -->
<main class="container mx-auto px-4 py-8">
    <!-- 简介 -->
    <section class="mb-10 bg-white p-6 rounded-lg shadow-sm">
        <h2 class="text-xl font-semibold mb-3 flex items-center">
            <i class="fa fa-info-circle text-primary mr-2"></i>
            关于 DevBox
        </h2>
        <p class="text-gray-600">
            DevBox 是 OpenHarmony PC 开发者工具，提供了一系列命令行工具来帮助开发者进行项目构建、调试和部署。
        </p>
    </section>

    <!-- 命令列表 -->
    <section>
        <h2 class="text-xl font-semibold mb-6 flex items-center">
            <i class="fa fa-list-ul text-primary mr-2"></i>
            命令列表
        </h2>

        <div id="commands-container" class="grid grid-cols-1 md:grid-cols-2 gap-6"></div>

        <!-- 加载提示 -->
        <div id="loading" class="text-center py-10">
            <i class="fa fa-spinner fa-spin text-primary text-2xl mb-2"></i>
            <p class="text-gray-500">正在加载命令手册...</p>
        </div>

        <!-- 错误提示 -->
        <div id="error" class="text-center py-10 hidden">
            <i class="fa fa-exclamation-circle text-red-500 text-2xl mb-2"></i>
            <p class="text-red-500">加载命令手册失败，请稍后重试</p>
        </div>
    </section>
</main>

<!-- 页脚 -->
<footer class="bg-dark text-white py-8 mt-12">
    <div class="container mx-auto px-4">
        <div class="text-center">
            <p class="text-gray-400">© 2025 DevBox 命令手册</p>
        </div>
    </div>
</footer>

<!-- JavaScript -->
<script>
    let commandData = []; // 全局存储命令数据
    const commandsContainer = document.getElementById('commands-container');
    const searchInput = document.getElementById('search-input');
    const searchResults = document.getElementById('search-results');
    const loadingIndicator = document.getElementById('loading');
    const errorIndicator = document.getElementById('error');

    // 防抖函数（减少搜索频繁触发）
    function debounce(func, delay = 300) {
      let timeoutId;
      return function(...args) {
        clearTimeout(timeoutId);
        timeoutId = setTimeout(() => func.apply(this, args), delay);
      };
    }

    // 初始化页面（异步加载数据）
    async function initPage() {
      try {
        // 加载命令数据
        const response = await fetch('commands.json');
        if (!response.ok) throw new Error('数据加载失败');
        commandData = await response.json();

        // 隐藏加载提示，渲染卡片（仅头部）
        loadingIndicator.classList.add('hidden');
        renderCommandCards(commandData);

        // 添加事件监听
        searchInput.addEventListener('input', debounce(handleSearch));
        searchInput.addEventListener('focus', handleSearchFocus);
        document.addEventListener('click', handleDocumentClick);
        addCommandCardClickEvents();

      } catch (error) {
        console.error('初始化失败:', error);
        loadingIndicator.classList.add('hidden');
        errorIndicator.classList.remove('hidden');
      }
    }

    // 渲染命令卡片（仅头部，身体部分按需加载）
    function renderCommandCards(commands) {
      commandsContainer.innerHTML = '';
      if (commands.length === 0) {
        commandsContainer.innerHTML = `
          <div class="col-span-full text-center py-10">
            <i class="fa fa-search text-gray-300 text-2xl mb-2"></i>
            <p class="text-gray-500">没有找到匹配的命令</p>
          </div>
        `;
        return;
      }

      // 批量构建 HTML，减少 DOM 操作
      let cardsHTML = '';
      commands.forEach((command, index) => {
        cardsHTML += `
          <div class="command-card border border-gray-200" data-index="${index}">
            <div class="command-header">
              <div>
                <h3 class="font-mono font-bold text-primary">${command.name}</h3>
                <p class="text-sm text-gray-500 mt-1">${command.description}</p>
              </div>
              <i class="fa fa-chevron-down text-gray-400 transition-transform duration-300"></i>
            </div>
            <div class="command-body hidden" data-loaded="false"></div>
          </div>
        `;
      });
      commandsContainer.innerHTML = cardsHTML;
    }

    // 处理搜索
    function handleSearch() {
      const searchTerm = searchInput.value.trim().toLowerCase();
      if (!searchTerm) {
        searchResults.classList.add('hidden');
        renderCommandCards(commandData);
        addCommandCardClickEvents();
        return;
      }

      // 过滤匹配命令
      const matchedCommands = commandData.filter(command => {
        const nameMatch = command.name.toLowerCase().includes(searchTerm);
        const descMatch = command.description.toLowerCase().includes(searchTerm);
        const optionMatch = command.options?.some(opt =>
          opt.name.toLowerCase().includes(searchTerm) || opt.description.toLowerCase().includes(searchTerm)
        );
        const exampleMatch = command.examples?.some(ex => ex.toLowerCase().includes(searchTerm));
        return nameMatch || descMatch || optionMatch || exampleMatch;
      });

      displaySearchResults(matchedCommands, searchTerm);
      renderCommandCards(matchedCommands);
      addCommandCardClickEvents();
    }

    // 显示搜索结果
    function displaySearchResults(matchedCommands, searchTerm) {
      searchResults.innerHTML = matchedCommands.length
        ? `<div class="px-4 py-2 bg-gray-50 text-sm text-gray-500 border-b border-gray-100">找到 ${matchedCommands.length} 个匹配结果</div>`
        : `<div class="px-4 py-3 text-gray-500">没有找到匹配 "${searchTerm}" 的命令</div>`;

      matchedCommands.slice(0, 5).forEach(command => {
        const item = document.createElement('div');
        item.className = 'px-4 py-3 hover:bg-gray-50 cursor-pointer transition-colors';
        item.innerHTML = `
          <div class="font-mono font-bold text-primary">${highlightSearchTerm(command.name, searchTerm)}</div>
          <div class="text-sm text-gray-500 mt-1">${highlightSearchTerm(command.description, searchTerm)}</div>
        `;
        item.addEventListener('click', () => {
          searchInput.value = command.name;
          searchResults.classList.add('hidden');
          renderCommandCards([command]);
          addCommandCardClickEvents();
          // 滚动到卡片
          setTimeout(() => {
            const card = document.querySelector(`.command-card[data-index="${commandData.findIndex(c => c.name === command.name)}"]`);
            if (card) {
              card.scrollIntoView({ behavior: 'smooth' });
              card.classList.add('ring-2', 'ring-primary/30');
              setTimeout(() => card.classList.remove('ring-2', 'ring-primary/30'), 2000);
            }
          }, 0);
        });
        searchResults.appendChild(item);
      });

      searchResults.classList.remove('hidden');
    }

    // 高亮搜索关键词
    function highlightSearchTerm(text, term) {
      return text.replace(new RegExp(`(${term})`, 'gi'), '<span class="search-highlight">$1</span>');
    }

    // 搜索框聚焦时触发搜索
    function handleSearchFocus() {
      if (searchInput.value.trim()) handleSearch();
    }

    // 点击文档空白处隐藏搜索结果
    function handleDocumentClick(e) {
      if (!searchInput.contains(e.target) && !searchResults.contains(e.target)) {
        searchResults.classList.add('hidden');
      }
    }

    // 命令卡片点击事件（按需渲染身体部分）
    function addCommandCardClickEvents() {
      document.querySelectorAll('.command-header').forEach(header => {
        header.addEventListener('click', () => {
          const card = header.parentElement;
          const body = card.querySelector('.command-body');
          const icon = header.querySelector('.fa-chevron-down');
          const index = parseInt(card.dataset.index);
          const command = commandData[index];

          // 未加载则渲染身体内容
          if (body.dataset.loaded === 'false') {
            let bodyHTML = `
              <div class="mb-4">
                <h4 class="font-semibold text-sm text-gray-700 mb-2">语法:</h4>
                <pre class="bg-gray-50 p-3 rounded-md text-sm font-mono overflow-x-auto">${command.syntax}</pre>
              </div>
            `;

            // 渲染选项
            if (command.options) {
              bodyHTML += `
                <div class="mb-4">
                  <h4 class="font-semibold text-sm text-gray-700 mb-2">选项:</h4>
                  <div class="space-y-2">
                    ${command.options.map(opt => `
                      <div class="flex">
                        <code class="bg-gray-50 px-2 py-1 rounded text-sm font-mono mr-2 whitespace-nowrap">${opt.name}</code>
                        <span class="text-sm">${opt.description}</span>
                      </div>
                    `).join('')}
                  </div>
                </div>
              `;
            }

            // 渲染示例
            if (command.examples) {
              bodyHTML += `
                <div>
                  <h4 class="font-semibold text-sm text-gray-700 mb-2">示例:</h4>
                  <div class="space-y-2">
                    ${command.examples.map(ex => `
                      <pre class="bg-gray-50 p-3 rounded-md text-sm font-mono overflow-x-auto">${ex}</pre>
                    `).join('')}
                  </div>
                </div>
              `;
            }

            body.innerHTML = bodyHTML;
            body.dataset.loaded = 'true';
          }

          // 切换显示/隐藏
          body.classList.toggle('hidden');
          icon.classList.toggle('rotate-180');
        });
      });
    }

    // 页面加载完成后初始化
    document.addEventListener('DOMContentLoaded', initPage);
</script>
</body>
</html>